// 加载Express模块
const express = require('express');

// 加载MySQL模块
const mysql = require('mysql');

// 加载bodyParser模块
const bodyParser = require('body-parser');

// 加载MD5模块
const md5 = require('md5');

// 创建MySQL连接池
const pool = mysql.createPool({
  host: '127.0.0.1',        //MySQL服务器地址
  port: 3306,                   //MySQL服务器端口号
  user: 'root',                 //数据库用户的用户名
  password: '',                 //数据库用户密码
  database: 'project_8424',     //数据库名称
  connectionLimit: 20,          //最大连接数
  charset: 'utf8'               //数据库服务器的编码方式
});

// 创建服务器对象
const app = express();

app.use(bodyParser.urlencoded({
  extended: false
}));


// 加载CORS模块
const cors = require('cors');

// 使用CORS中间件
app.use(cors({
  origin: ['http://localhost:8080', 'http://127.0.0.1:8080']
}));

app.use( express.static('./public') );

//用户注册接口
app.post('/register',(req,res,next)=>{
    //1.1获取post请求的数据
    var obj = req.body;
    //1.2验证各项数据是否为空
    var i = 200;  //定义返回的状态码
    for (var k in obj) {
        i++;
        if (!obj[k]) {
            res.send({ code: i, message: k + "不能为空" });
            //如果为空，阻止往后执行
            return;
        }
    }
    //1.3执行SQL命令
    let sql = "SELECT uid FROM user WHERE uname=? or uphone=?";
    //执行SQL语句
    pool.query(sql, [obj.uname,obj.uphone], (err, result) => {
        if (err) {
            next(err);
            return;
        };
        //查询返回的结果是数组,如果是空数组说明没有该用户名，否则存在
        if (result.length === 0) {
            var sql = "INSERT INTO user (uid,uname,upwd,uphone) VALUES(NULL,?,?,?)";
            pool.query(sql, [obj.uname, obj.upwd, obj.uphone], (err, result) => {
                //错误处理
                if (err) {
                    next(err);
                    //阻止往后执行
                    return;
                };
                //执行成功
                //SQL命令执行成功的结果result，格式为对象
                //如果对象下的affectedRows为0，说明插入失败，否则说明插入成功
                if (result.affectedRows > 0) {
                    res.send({ code: 200, message: "注册成功" })
                } else {
                    res.send({ code: 201, message: "注册失败" })
                }
            });
        } else {
            res.send({ code: 201, message: "用户名或手机号已被使用" });
        }
    });
});

//轮播图片接口
app.get('/lunbo',(req,res,next)=>{
    // SQL语句以获取轮播路径
    let sql = 'SELECT cid,c_image FROM carousel ORDER BY cid';
    // 执行SQL语句
    pool.query(sql, (err, result) => {
        if (err){
            next(err);
            return;
        };
        res.send({ message: 'ok', code: 200, result: result });
    })
});

//用户名登录接口
app.post('/login',(req,res,next)=>{
    let obj=req.body;
    if (!obj.uname){
        res.send({code:201,message:"用户名不能为空"});
        return;
    }
    if(!obj.upwd){
        res.send({code:202,message:"密码不能为空"});
        return;
    }
    //执行SQL命令
    let sql='select * from user where uname=? and upwd=?'
    pool.query(sql,[obj.uname,obj.upwd],(err,result)=>{
        if(err){
            next(err);
            return;
        };
        if(result.length===0){
            res.send({code:201,message:"用户名或密码不正确"})
        }else{
            res.send({code:200,message:"登录成功"})
        }
    })
});

//手机号登录
app.post('/phone',(req,res,next)=>{
    let obj=req.body;
    //执行SQL命令
    let sql='select * from user where uphone=? and upwd=?'
    pool.query(sql,[obj.uphone,obj.upwd],(err,result)=>{
        if(err){
            next(err);
            return;
        };
        if(result.length===0){
            res.send({code:201,message:"手机号或密码不正确"})
        }else{
            res.send({code:200,message:"登录成功"})
        }
    })
});

//获取用户信息接口
app.get('/user',(req,res,next)=>{
    pool.query('select uid,user_name,uname,uphone,usex from user',(err,result)=>{
        if(err){
            next(err);
            return;
        };
        // console.log(result);
        if(!result.RowDataPacket){
            res.send({code:200,msg:"查询成功",result})
        }else{
            res.send({code:201,msg:"查询失败"})
        }
    })

})

//获取订单信息接口
app.get('/zqorder',(req,res,next)=>{
    let sql = 'select * from cs_order';
    pool.query(sql,(err,result)=>{
        if(err){
            next(err);
            return;
        };
        res.send({message: 'ok', code: 200, result: result })
    })
})

//获取所有商品分类的接口
app.get('/sort',(req,res,next)=>{
    // SQL语句以获取商品分类表的数据
    let sql = 'SELECT sid,sname FROM sort ORDER BY sid';
    // 执行SQL语句
    pool.query(sql, (err, result) => {
        if (err){
            next(err);
            return;
        };
        res.send({ message: 'ok', code: 200, result: result });
    })
});

//商品所有信息接口
app.get('/allarticles',(req,res,next)=>{
    // SQL语句以获取轮播路径
    let sql = 'SELECT * FROM article';
    // 执行SQL语句
    pool.query(sql, (err, result) => {
        if (err){
            next(err);
            return;
        };
        res.send({ message: 'ok', code: 200, result: result });
    })
});

//获取特定商品数据的接口
app.get('/detail',(req,res,next)=>{
    //获取地址栏中的id参数
    let id = req.query.id;

    // SQL查询
    let sql = "SELECT r.did,dtitle,d_image,dprice,dintroduce FROM details AS r INNER JOIN article AS u ON art_id = u.aid WHERE r.did=?";

    // 执行SQL查询
    pool.query(sql, [id], (err, result) => {
        if (err){
            next(err);
            return
        };
        // 返回数据到客户端
        res.send({ message: 'ok', code: 200, result: result[0] });
    });
})

// 获取指定分类下包含商品数据的接口
app.get('/article', (req, res, next) => {
    // 获取客户端传递的cid参数
    let cid = req.query.cid;
  
    // 获取客户端传递的page参数
    let page = req.query.page? req.query.page : 1;
  
    // 存储每页显示的记录数
    let pagesize = 6;
  
    // 通过公式来计算从第几条记录开始返回
    let offset = (page - 1) * pagesize;
  
    // 用于存储获取到的总记录数
    let rowcount;
  
    // 获取指定分类下的文章总数
    let sql = 'SELECT COUNT(aid) AS count FROM article WHERE sort_id=?';
  
    pool.query(sql, [cid], (err, result) => {
        if (err){
            next(err);
            return;
        };
        // 将获取到总记录数赋给rowcount变量
        rowcount = result[0].count;

        // 根据总记录数和每页显示的记录数来计算总页数
        let pagecount = Math.ceil(rowcount / pagesize);
  
        // 查询SQL语句
        sql = 'SELECT aid,aname,a_image,aprice,anum FROM article WHERE sort_id=? LIMIT ?,?';
        // 执行SQL
        pool.query(sql, [cid, offset, pagesize], (err, result) => {
            if (err){
                next(err);
                return;
            };
            res.send({ message: 'ok', code: 200, result: result, pagecount: pagecount });
        });
    });
});

//购物车数据接口
app.get('/carlist',(req,res,next)=>{
    //获取地址栏中的id参数
    let id=req.query.id;
    //sql查询
    let sql="SELECT r.did,dtitle,d_image,dprice,dintroduce FROM shopping_car AS r INNER JOIN user AS u ON user_id = u.uid WHERE r.car_id=?"
    // 执行SQL查询
    pool.query(sql, [id], (err, result) => {
        if (err){
            next(err)
            return
        };
        // 返回数据到客户端
        res.send({ message: 'ok', code: 200, result: result[0] });
    });
})
//删除购物车接口

//显示收藏列表接口
app.get('/collectlist',(req,res,next)=>{
    //获取地址栏中的用户id参数
    let id=req.query.uid;
    //sql查询某个用户的收藏列表
    let sql="select * from article where aid=(select col_id from collect where uid=?)"
    // 执行SQL查询
    pool.query(sql, [uid], (err, result) => {
        if (err){
            next(err)
            return
        };
        // 返回数据到客户端
        res.send({ message: 'ok', code: 200, result: result[0] });
    });
})

//删除收藏接口。传递收藏编号
app.delete('/delcollect:col_id',(req,res,next)=>{
    let obj=req.params;
    let sql="delete from collect where col_id=?"
    pool.query(sql,[obj.foot_id],(err,result)=>{
        if(err){
            next(err)
            return
        }
        if(result.affectedRows===0){
            res.send({code:201,message:"删除失败"})
        }else{
            res.send({code:200,message:"删除成功"})
        }
    })
});

//添加收藏的接口
app.get('/addcollect',(req,res,next)=>{
    //获取商品详情的id
    let id=req.query.id
    let time=new Date();
    let sql="insert into collect(col_id,col_time) values(?,?)"
    pool.query(sql,[id,time],(err,result)=>{
        if(err){
            next(err);
            return
        }
        //返回数据到客户端
        res.send({message:"ok",code:200})
    })
});

//显示足迹接口
app.get('/foot',(req,res,next)=>{
    //获取地址栏中的用户id参数
    let id=req.query.id;
    //sql查询
    let sql=""
    // 执行SQL查询
    pool.query(sql, [id], (err, result) => {
        if (err){
            next(err)
            return
        };
        // 返回数据到客户端
        res.send({ message: 'ok', code: 200, result: result[0] });
    });
})

//删除足迹接口
app.delete('/delfoot:foot_id',(req,res,next)=>{
    let obj=req.params;
    let sql="delete from foot where foot_id=?"
    pool.query(sql,[obj.foot_id],(err,result)=>{
        if(err){
            next(err)
            return
        }
        if(result.affectedRows===0){
            res.send({code:201,message:"删除失败"})
        }else{
            res.send({code:200,message:"删除成功"})
        }
    })
});

//添加足迹接口
app.get('/addfoot',(req,res,next)=>{
    //获取商品详情的id
    let id=req.query.id
    let time=new Date();
    let sql="insert into foot(foot_id,foot_time) values(?,?)"
    pool.query(sql,[id,time],(err,result)=>{
        if(err){
            next(err);
            return
        }
        //返回数据到客户端
        res.send({message:"ok",code:200})
    })
});


const socketIO=require('socket.io');
const http=require('http').createServer(app);
const io = socketIO(http,{
    cors: {
        origin: 'http://localhost:8080'
    }
});

var users=[];   //保存进入房间的用户
let admin_list = {}  //用于存储每个用户的socket，实现私聊的功能
io.on('connection',(socket) => {
    console.log("有用户加进来了",socket.id) // 输出客户端的id
    /**********************************直播间发送消息的区域***************************** */
    // 接收进入直播间的用户姓名
    socket.on('userlist',(data)=>{
        //判断，如果data在users中存在，说明该用户已经进入了直播间，不要加到用户列表中
        //如果data在users中不存在，说明该用户没有进入直播间，把用户的name加到用户列表中
        // console.log(data.username)
        var user=users.find(item=>item.username===data.username)
        if(user){
            //表示用户存在
            return
        }else{
            users.push(data.username)
            //告诉所有的用户，有用户加入了直播间
            io.emit("adduser",data)
            //告诉所有人直播间有多少人
            // console.log(users.length)
            io.emit('count_updated', users.length);
            // //把登录成功的用户名存储起来
            socket.username=data.username
        }
    });
    //接收直播间发来的消息
    socket.on("sendMsg",(data)=>{
        io.emit("sendtext",data)
    });
    //退出直播间时
    socket.on("dislive",(data)=>{
        // 用户退出了直播间
        io.emit("outuser",data)
        // console.log(data.username)
        users.splice(users.findIndex(item => item === data.username), 1);
        // console.log(users)
        io.emit('count_updated', users.length);
    });
    //******************************************************************************* */

    //***********************与客服聊天发送信息的区域**********************************/
    //接收进入客服聊天界面的客服名称
    socket.on("weallist",(data)=>{
        admin_list[data.user]=socket
        console.log("进入消息页的人员列表",admin_list)
    })

    //退出登录时，执行销毁列表操作
    socket.on("disweal",(data)=>{
        admin_list
        console.log("销毁管理员列表",admin_list)
    })

    //服务器接收用户发送给客服的消息
    socket.on("sendword",(data)=>{
        console.log(data)
        //消息返回给自己
        socket.emit("receviceMessage",data)
        //向客服私发消息
        let target=admin_list[data.to]
        if(target){
            //发送至指定的人
            target.emit("wealSend",data)
        }
    })
    //服务器接收客服给用户发送的消息
    socket.on("sendserver",(data)=>{
        socket.emit("wealSend",data)
        //向用户私发消息
        let target=admin_list[data.to]
        if(target){
            //发送至指定的人
            target.emit("receviceMessage",data)
        }
    })

    //******************************************************************************* */
    // 监听客户端的断开
    socket.on('disconnect', (reason)=>{
        // 断开时，当前在线人数--
        console.log(socket.id,"已退出")
    })
})



// 指定服务器对象监听的端口号
http.listen(3000, () => {
    console.log('server is running...');
});

//错误处理中间件
app.use((err,req,res,next)=>{
	//err接收的错误
	console.log(err);
	res.send({code:500,message:'服务器端错误'})
});
